#include "loginbusiness.h"

// 登陆业务
CWHttpReply LoginBusiness::doBusiness(CWHttpRequest &request)
{
    if (handleBody(request))
    {
        int isLogined = checkUserLogined();
        // redis中未查询到登陆
        if (isLogined == -1)
        {
            // 在mysql中查询用户是否存在
            m_name = doSql();
            if (m_name != "")
            {
                Json::Value root;
                int token = makeToken();
                root["token"] = token;
                // 保存token成功
                if (saveToken(token))
                {
                    root["user_name"] = m_name;
                    m_body = root.toStyledString();
                }
                else // token保存到redis中失败
                {
                    m_statuscode = 203;
                    m_body = "";
                }
            }
        }
        else // 如果在redis查询到用户已经登陆
        {
            Json::Value root;
            root["token"] = isLogined;
            root["user_name"] = m_name;
            m_body = root.toStyledString();
            std::cout << m_body << std::endl;
        }
    }
    CWHttpReply reply(request.getRequestVersion().c_str(), m_statuscode, "OK");
    reply.setReplyHeader("Content-Type", "application/json");
    reply.setReplyHeader("Content-Length", std::to_string(m_body.size()).c_str());
    reply.setReplyData(m_body.c_str());
    return reply;
}

bool LoginBusiness::handleBody(CWHttpRequest &request)
{
    Json::Reader reader;
    Json::Value root;
    if (reader.parse(request.getRequestBody(), root))
    {
        m_id = root["user_id"].asString();
        m_pwd = root["user_pwd"].asString();
    }
    else
    {
        m_statuscode = 202;
        return false;
    }
    return true;
}

std::string LoginBusiness::doSql()
{
    m_statuscode = 203;
    MysqlConn conn;
    if (conn.connect("root", "Xitieyi200299", "lovechat", "127.0.0.1"))
    {
        std::string SQL =
            R"(select user_name from user where user_id=")" + m_id +
            R"(" and user_pwd=")" + m_pwd +
            R"(")";
        if (conn.query(SQL.c_str()))
        {
            if (conn.next())
            {
                m_statuscode = 200;
                return conn.value(0);
            }
            else
                m_statuscode = 201;
        }
    }
    return std::string();
}

int LoginBusiness::makeToken()
{
    std::default_random_engine e;
    std::uniform_int_distribution<int> u(10000000, 99999999);
    e.seed(time(0));
    return u(e);
}

bool LoginBusiness::saveToken(int token)
{
    RedisConn conn;
    if (!conn.connect("127.0.0.1", 6379))
        return false;
    std::string command = "set ";
    command += m_id + ' ' + std::to_string(token) + " NX EX 10";
    if (!conn.executeCommand(command.c_str()))
        return false;
    command = "set " + m_id + ' ' + m_name + " NX EX 10";
    return conn.executeCommand(command.c_str());
}

std::string LoginBusiness::getSaveUserName(int token)
{
    RedisConn conn;
    if (!conn.connect("127.0.0.1", 6379))
        return std::string();
    std::string command = "get ";
    command += std::to_string(token);
    if (!conn.executeCommand(command.c_str()))
        return std::string();
    if (conn.getReplyType() == ReplyType::kReturnNil)
        return std::string();
    return conn.getRetString();
}

int LoginBusiness::checkUserLogined()
{
    int ret = 0;
    RedisConn conn;
    if (!conn.connect("127.0.0.1"))
        return -1;
    std::string command = "get ";
    command += m_id;
    if (!conn.executeCommand(command.c_str()))
        return -1;
    if (conn.getReplyType() == ReplyType::kReturnNil)
        return -1;
    ret = atoi(conn.getRetString());
    command = "get " + m_id;
    conn.executeCommand(command.c_str());
    m_name = conn.getRetString();
    return ret;
}